其實在 React 16 時就有 Suspense
,需要搭配 lazy
使用。使用原因是為了優化效能,減少初始的 JavaScript bundle 大小。可以達到延遲載入的效果,只在需要的時候才載入元件。
import { lazy, Suspense } from "react";
const LazyComponent = lazy(() => import("./LazyComponent"));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
React 18 的 Suspense 不僅解決了元件 Lazy Loading,還進一步用來處理資料載入和 Server-Side Rendering (SSR) 的優化。
React 18 中的 Suspense 透過 Streaming 和 Selective Hydration 技術來優化效能,讓頁面更快進行互動。這部份的 SSR 通常會使用框架來達成,像是 Next.js, Remix 等。
允許將頁面的 HTML 分解為較小的塊,並逐步將這些塊發送到用戶端。以餐廳來舉例,傳統 SSR 的作法是等所有菜都準備好後才一起端上桌,而 Streaming 則允許某道菜準備好後就立刻上桌,讓客人可以更快吃到飯菜。
兩個差別會長這樣:
傳統的 SSR 中,必須等到所有資料和 HTML 都準備好,才能顯示畫面。
Streaming 的渲染流程,當部分內容準備好後,就可以先送回給瀏覽器進行渲染。
這樣的分段渲染可以減少 Client 的等待時間,從而提升效能和用戶體驗。
Selective Hydration 允許在 hydration 過程中,根據用戶的行為,優先處理使用者互動的區域。當使用者與某個元件互動時,React 會優先對這些元件進行 hydration,而不必等整個頁面完成。
例如,當用戶點擊一個尚未完成 hydration 的按鈕時,React 會中斷其他元件的 Hydration,會優先處理用戶點擊的區域,從而提供即時回饋。
在 React 18 中,Suspense 是基於 Promise 的概念運作。當 Suspense 等待一個 Promise 完成時,它會顯示一個 fallback UI,直到 Promise 被 resolve 或 reject。
另外 Suspense 能實現也是基於 React 18 的 Concurrent Rendering 和 Fiber 架構,詳細內容會在之後的文章分享。
參考資料和圖片來源:
https://react.dev/reference/react/Suspense
https://github.com/reactwg/react-18/discussions/37
https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
https://www.youtube.com/watch?v=pj5N-Khihgc&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa&index=4